#ifndef CMD_H_
#define CMD_H_

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>

#include "../global.h"
#include "../constants.h"
#include "../process/process.h"
#include "../string/string.h"
#include "../history/history.h"

#define WEXITSTATUS(w) ((signed char)(((w) >> 8) & 0xff))

/* Conector de dois comandos */
typedef struct connector
{
	int type; /* Tipo */
	struct command *next; /* Próximo comando */
} connector;

/* Comando */
typedef struct command
{
	int type; /* Tipo */
	int ground; /* FG ou BG*/
	linked_list *args; /* Argumentos */
	int out_fd; /* Arquivo de saída */
	int in_fd; /* Arquivo de entrada */
	int err_fd; /* Arquivo de erro */
	connector *connec; /* Conector */
} command;

/* Cria um novo conector */
connector *connector_new();
/* Deleta um conetor */
void connector_delete(void *connec);
/* Verifica se a string str é um conector */
int is_connector(string *str);
/* Verifica se a string é um caracter de redirecionamento de ES */
int is_redirect_char(string *str);

/* Cria um novo comando */
command *command_new();
/* Delete um novo comando */
void command_delete(void *cmd);
/* Verifica se o comando está vazio */
int command_is_empty();

/* Executa um comando */
int execute_command(command *cmd);
/* Transforma a lista de argumentos em um array de char [] */
char **args_to_argv(command *cmd);

/* Executa um comando externo */
int execute_external_cmd(command *cmd);
/* Espera o filho com pid terminar sua execução */
int wait_child(pid_t pid);
/* Redireciona a E/S */
void redirect_io(command *cmd);
/* Retorna a E/S */
void unredirect_io(command *cmd);

/* Verifica se a string é um comando interno */
int is_internal_cmd(string *str);
/* Executa um comando interno */
int execute_internal_cmd(command *cmd);
/* Executa o help */
void builtin_help();
/* Executa o jobs */
void builtin_jobs();
/* Executa fg (mode=1) ou bg (mode=2) */
void builtin_fg_bg(string *pid, int mode);
/* Executa o cd */
void builtin_cd(string *path);
/* Executa o pwd */
void builtin_pwd();
/* Executa o history */
void builtin_history();

#endif /* CMD_H_ */
